package com.hliushi.learn.exception;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Objects;


/**
 * 针对 web层的 全局异常处理
 *
 * @author llhuang10
 * @date 2021/8/24 8:54
 */
@ResponseBody
@ControllerAdvice(annotations = {RestController.class, Controller.class})
public class ExceptionConfiguration {


    /**
     * 异常处理的方法
     * 指定抓这三个异常
     * 其中
     * ConstraintViolationException 是针对单个属性的校验的,  比如  @NotNull String userId
     * #
     * MethodArgumentNotValidException 是针个一个整体对象校验, 比如  @Valid User user
     */
    @ExceptionHandler({ConstraintViolationException.class, BindException.class, MethodArgumentNotValidException.class})
    public String exHandler(Exception ex, HttpServletRequest request) {
        String msg = "";
        ex.printStackTrace();
        if (ex instanceof ConstraintViolationException) {
            ConstraintViolationException violationException = (ConstraintViolationException) ex;
            // 获取异常信息
            ConstraintViolation<?> next = violationException.getConstraintViolations().iterator().next();
            msg = next.getMessage();
        } else if (ex instanceof BindException) {
            BindException bindException = (BindException) ex;
            msg = Objects.requireNonNull(bindException.getBindingResult().getFieldError()).getDefaultMessage();
        } else if (ex instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException methodArgumentNotValidException = (MethodArgumentNotValidException) ex;
            msg = Objects.requireNonNull(methodArgumentNotValidException.getBindingResult().getFieldError()).getDefaultMessage();
        }
        return msg;
    }

}
